<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
</head>

<body>
    <script>
        /*
            全局作用域下，this指向window
            */
        console.log(window === this); // true
        var a = 1;
        this.b = 2;
        window.c = 3;
        console.log(a + b + c); // 6

        /*
        在函数内部，this的值取决于函数被调用的方式
        直接调用，this会指向全局变量window
        */
        function foo() {
            return this;
        }
        console.log(foo() === window); // true

        /*
        一般来说，this总会指向赖以运行的作用域，但是使用call和apply方法，就会改变this的指向
        call和apply第一参数为this指向，后续散列参数均为函数调用所需形参，而在apply中这些参数被包裹在一个数组中
        */
        var person = {
            name: "lyl",
            age: 25
        };

        function say(job) {
            console.log(this.name + ":" + this.age + " " + job);
        }
        //调用say方法，原来this直接指向window,使用call和apply修改this指向了person这个对象；从第二个参数＂ＦＥ＂才是取代形参　ｊｏｂ的
        say.call(person, "FE"); // lyl:25　ＦＥ
        say.apply(person, ["FE"]); // lyl:25　ＦＥ

        /*
        bind 和call apply相似，也是将this指向改变到第一参数,区别在于：
        bind以后不会立即执行这个方法，而是需要用变量接收，再去调用
        */
        var person = {
            name: "axuebin",
            age: 25
        };

        function say() {
            console.log(this.name + ":" + this.age);
            return this;
        }
        var f = say.bind(person);
        console.log(f());

        /*
        箭头函数 箭头函数会捕获其所在上下文的this值，作为自己的this值
        */
        function Person(name) {
            this.name = name;
            this.say = () => { //此时箭头函数内的this指向的是person,即实例对象
                var name = "ll";
                return this.name;
            }
        }
        var person = new Person("lyl");
        console.log(person.say()); // lyl

        /*
        作为对象的一个方法 this指向调用函数的对象
        */
        var person = {
            name: "lyl",
            getName: function () {
                return this.name;
            }
        }
        console.log(person.getName()); // lyl   对象person直接调用 getName ,this指向person
        //另外一种情况
        var name = "yr";
        var person = {
            name: "lyl",
            getName: function () {
                return this.name;
            }
        }
        var getName = person.getName;
        console.log(getName()); // yr this的指向是被谁调用  这里getName方法另存了一下，然后直接调用，即window调用，所以this指向window

        /*
        作为一个构造函数 this被绑定到正在构造的新对象
        通过构造函数创建一个对象执行以下几个步骤:
        1.创建新对象
        2.将this指向这个对象
        3.给对象赋值(属性和方法)
        4.返回this
        */
        function Person(name) {
            this.name = name;
            this.age = 25;
            this.say = function () {
                console.log(this.name + ":" + this.age);
            }
        }
        var person = new Person("lyl");
        console.log(person.name); // lyl
        person.say(); // lyl:25
    </script>
</body>

</html>